package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.mapper.CartInfoMapper;
import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 购物车管理
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private CartInfoMapper cartInfoMapper;
    @Autowired
    private ProductFeignClient productFeignClient;


    //加入购物车
    @Override
    public CartInfo addCart(Long skuId, Integer skuNum) {

        //随意在任何地方获取请求响应对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //真实用户
        //String userId = request.getHeader("userId");
        String userId = AuthContextHolder.getUserId(request);
        //临时用户
        if(StringUtils.isEmpty(userId)){
            //userId = request.getHeader("userTempId");
            userId = AuthContextHolder.getUserTempId(request);
        }
        //1:判断当前商品skuId 是否在购物车表中已经存在
        //2个条件  分别是：用户ID  skuId
        CartInfo cartInfo = cartInfoMapper.selectOne(new QueryWrapper<CartInfo>()
                .eq("user_id", userId)
                .eq("sku_id", skuId));
        if(null != cartInfo){
            //2:存在  追加商品的数量
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            //更新实时价格
            BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
            cartInfo.setSkuPrice(skuPrice);
            //勾选中
            cartInfo.setIsChecked(1);
            //更新数据库
            cartInfoMapper.updateById(cartInfo);
        }else{
            //3:不存在 新增一个商品
            //创建购物车对象
            cartInfo = new CartInfo();
            //设置用户ID
            cartInfo.setUserId(userId);
            //设置SkuId
            cartInfo.setSkuId(skuId);
            //设置数量
            cartInfo.setSkuNum(skuNum);

            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            //放入购物车时的价格
            cartInfo.setCartPrice(skuInfo.getPrice());
            //实时价格
            cartInfo.setSkuPrice(skuInfo.getPrice());
            //名称
            cartInfo.setSkuName(skuInfo.getSkuName());
            ////图片
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            //保存
            cartInfoMapper.insert(cartInfo);
        }
        return cartInfo;
    }

    // //完成购物车查询（可能包含合并） （如果合并 记得删除临时用户的购物车）
    @Override
    public List<CartInfo> cartList(String userId, String userTempId) {
        //1:查询真实用户的购物车集合
        List<CartInfo> cartInfoListByUserId = getCartInfoList(userId);
        //2：查询临时用户的购物车集合
        List<CartInfo> cartInfoListByUserTempId = getCartInfoList(userTempId);
        //3:合并   真实用户如果不存在  临时用户肯定存在
        //1)先判断真实用户ID是否NULLL
        if(!StringUtils.isEmpty(userId)){
            //真实用户是存在的  表示用户已经登录
            //判断临时购物车集合在不在
            if(!CollectionUtils.isEmpty(cartInfoListByUserTempId)){
                //临时购物车是存在的
                //判断真实购物车是否存在
                if(!CollectionUtils.isEmpty(cartInfoListByUserId)){
                    //原来 真实用户的购物车集合 List<CartInfo>
                    //将真实用户的购物车集合转成Map对象
                    // Map<K,V>   K:skuId V:真实购物车对象  Map<Long,CartInfo>

                    Map<Long, CartInfo> cartInfoMapByUserId = cartInfoListByUserId.stream()
                            .collect(Collectors.toMap(CartInfo::getSkuId, cartInfo -> cartInfo));

                    //真实购物车存在  临时购物车也存在
                    for (CartInfo cartInfoByUserTemp : cartInfoListByUserTempId) {
                        //当前临时购物车 合并到 真实购物车集合 的时候
                        //1:判断当前临时购物车中的skuId 是否已经在真实购物车集合中已经存在了
                        CartInfo cartInfo = cartInfoMapByUserId.get(cartInfoByUserTemp.getSkuId());
                        if(null != cartInfo){
                            //存在 追加数量
                            cartInfo.setSkuNum(cartInfo.getSkuNum() + cartInfoByUserTemp.getSkuNum());
                            //同时 更新数据库中真实用户的购物车数量
                            cartInfoMapper.updateById(cartInfo);

                        }else{
                            //不存在 增加一份的新的购物车到真实购物车集合中
                            cartInfoMapByUserId.put(cartInfoByUserTemp.getSkuId(),cartInfoByUserTemp);
                            //不相同的购物车 更新临时用户Id 成 真实用户的ID
                            cartInfoByUserTemp.setUserId(userId);
                            cartInfoMapper.updateById(cartInfoByUserTemp);
                        }
                    }
                    //删除数据库中 临时用户的所有购物车
                    cartInfoMapper.delete(new QueryWrapper<CartInfo>().eq("user_id",userTempId));
                    return new ArrayList<>(cartInfoMapByUserId.values());
                }else{
                    //真实用户存在表示登录了 真实用户的购物车不存在
                    //数据库要将 cart_inf 的 user_id 字段由临时用户的ID 更改成真实用户ID
                    cartInfoListByUserTempId.forEach(cartInfoTemp -> {
                        cartInfoTemp.setUserId(userId);
                        cartInfoMapper.updateById(cartInfoTemp);
                    });
                    return cartInfoListByUserTempId;
                }
            }else{
                //临时购物车是不存在  即使真实用户的购物车也是不存在
                return cartInfoListByUserId;
            }
        }else{
            //真实用户是不存在  真实用户的购物车也是不存在
            return cartInfoListByUserTempId;
        }
    }
    //购物车中选中或取消
    @Override
    public void checkCart(Long skuId, String userId, Integer isChecked) {
        CartInfo cartInfo = new CartInfo();
        cartInfo.setIsChecked(isChecked);
        cartInfoMapper.update(cartInfo,new QueryWrapper<CartInfo>().eq("user_id",userId)
          .eq("sku_id",skuId));
    }
    //删除购物车
    @Override
    public void deleteCart(String userId, Long skuId) {
        cartInfoMapper.delete(new QueryWrapper<CartInfo>().eq("user_id",userId)
                .eq("sku_id",skuId));
    }

    @Override
    public Map<String, Object> getCartCheckedList(Long userId) {
        Map<String, Object> result = new HashMap<>();
        //1:查询订单详情集合
        //查询购物车 用户勾选的商品
        List<CartInfo> cartInfoList = cartInfoMapper.selectList(new QueryWrapper<CartInfo>()
                .eq("user_id", userId).eq("is_checked", 1));

        //将购物车中的数据导入订单详情对象中
        List<OrderDetail> orderDetailList = cartInfoList.stream().map(cartInfo -> {
            OrderDetail orderDetail = new OrderDetail();
            //订单详情：
            orderDetail.setSkuId(cartInfo.getSkuId());
            orderDetail.setSkuNum(cartInfo.getSkuNum());
            orderDetail.setSkuName(cartInfo.getSkuName());
            //远程调用商品微服务的价格
            BigDecimal skuPrice = productFeignClient.getSkuPrice(cartInfo.getSkuId());
            orderDetail.setOrderPrice(skuPrice);
            orderDetail.setImgUrl(cartInfo.getImgUrl());
            return orderDetail;
        }).collect(Collectors.toList());
        //设置订单详情集合
        result.put("detailArrayList",orderDetailList);

        //2:商品总件数
        long totalNum = orderDetailList.stream().
                collect(Collectors.summarizingInt(OrderDetail::getSkuNum)).getSum();
        result.put("totalNum",totalNum);
        //3:商品总金额
        double totalAmount = orderDetailList.stream().collect(Collectors.summarizingDouble(orderDetail -> {
            return orderDetail.getSkuNum() * orderDetail.getOrderPrice().doubleValue();
        })).getSum();
        result.put("totalAmount",totalAmount);
        return result;
    }

    //根据用户ID查询购物车集合
    private List<CartInfo> getCartInfoList(String userId){
        //判断真实用户ID 是否为NULL或“”
        if(!StringUtils.isEmpty(userId)){
            //查询真实用户的购物车
            List<CartInfo> cartInfoList = cartInfoMapper.
                    selectList(new QueryWrapper<CartInfo>().eq("user_id", userId));
            if(!CollectionUtils.isEmpty(cartInfoList)){
                //更新时时价格
                cartInfoList.forEach(cartInfo -> {
                    BigDecimal skuPrice = productFeignClient.getSkuPrice(cartInfo.getSkuId());
                    cartInfo.setSkuPrice(skuPrice);
                });
            }
            return cartInfoList;
        }
        return null;
    }
}
